/*
	Copyright (c) 2012 by karmaleaving@qq.com. All rights RESERVED.
*/
#ifndef __STD_QUEUE_H_VERSION_SSTD__
#define __STD_QUEUE_H_VERSION_SSTD__

#include "memory.hpp"
#include "algorithm.hpp"
#include "functional.hpp"
#include "deque.hpp"

SSTL_BEGIN
// CLASS queue {
template<typename Type, typename Container = SSTD::deque<Type>>
class queue
{
public:
	SSTD_NEST_TYPE_DEFINE(Type);
protected:
	Container _c;
public:
	queue()
	{
	}
	queue(queue const& o)
		: _c(o._c)
	{
	}
	bool empty()
	{
		return _c.empty();
	}
	void pop()
	{
		_c.pop_front();
	}
	void push(const_reference value)
	{
		_c.push_back(value);
	}
	size_type size()
	{
		return _c.size();
	}
	const_reference front() const
	{
		return _c.front();
	}
	reference front() const
	{
		return _c.front();
	}
	const_reference top() const
	{
		return _c.front();
	}
	reference top()
	{
		return _c.front();
	}
	void swap(queue& o)
	{
		_c.swap(o);
	}
#ifdef _USE_SSTD_EXTRA
	typedef Container container_type;
	container_type& get_container()
	{
		return _c;
	}
	container_type const& get_container() const
	{
		return _c;
	}
#endif // _USE_SSTD_EXTRA
};
// CLASS queue }
// FUNCTION swap (for queue) {
template<typename Type, typename Container>
inline void swap(queue<Type, Container>& left, queue<Type, Container>& right)
{
	left.swap(right);
}
// FUNCTION swap (for queue) }
// CLASS priority_queue {
template<typename Type, typename Container = vector<Type>, typename Compare = SSTD::less<Type>>
class priority_queue
{
public:
	SSTD_NEST_TYPE_DEFINE(Type);
protected:
	Container _c;
	Compare _comp;
	typedef _heap_<typename Container::iterator> heap;
public:
	priority_queue()
	{
	}
	explicit priority_queue(Compare const& comp)
		: _comp(comp)
	{
	}
	template<typename InIter>
	priority_queue(InIter first, InIter last, Compare const& comp)
		: _c(first, last), _comp(comp)
	{
		heap::make_heap(_c.begin(), _c.end(), _comp);
	}
	template<typename InIter>
	priority_queue(InIter first, InIter last)
		: _c(first, last)
	{
		heap::make_heap(_c.begin(), _c.end(), _comp);
	}
	void push(const_reference value)
	{
		_c.push_back(value);
		heap::push_heap(_c.begin(), _c.end(), _comp);
	}
	void pop()
	{
		heap::pop_heap(_c.begin(), _c.end(), _comp);
		_c.pop_back();
	}
	bool empty() const
	{
		return _c.empty();
	}
	size_type size() const
	{
		return _c.size();
	}
	const_reference top() const
	{
		return _c.front();
	}
	void swap(priority_queue& o)
	{
		_c.swap(o);
	}
#ifdef _USE_SSTD_EXTRA
	typedef Container container_type;
	container_type& get_container()
	{
		return _c;
	}
	container_type const& get_container() const
	{
		return _c;
	}
#endif // _USE_SSTD_EXTRA
};
// CLASS priority_queue }
// FUNCTION swap (for priority_queue) {
template<typename Type, typename Container>
inline void swap(priority_queue<Type, Container>& left,
	priority_queue<Type, Container>& right)
{
	left.swap(right);
}
// FUNCTION swap (for priority_queue) }
SSTL_END

#endif // __STD_QUEUE_H_VERSION_SSTD__
